#include "HttpServer.hpp"

const std::string SEP = "\r\n";
const std::string wwwroot = "./wwwroot";
const std::string default_HomePage = "index.html";

class HttpRequest
{
public:
    HttpRequest()
        : _path(wwwroot)
    {
    }

    ~HttpRequest()
    {
    }

    void Print()
    {
        std::cout << "method : " << _method << " url : " << _url << " _version : " << _version << " path : " << _path << " suffix : " << _suffix;  
    }

public:
    std::string _method;
    std::string _url;
    std::string _version;

    std::vector<std::string> _body;
    std::string _path;
    std::string _suffix;
};

HttpRequest stringstream(std::string &str)
{
    HttpRequest req; // 请求方法 url 版本
    std::string res = Util::ReadOneLine(str, SEP);
    Util::ParseLine(res,&req._method, &req._url, &req._version);

    while (!str.empty()) // 读取剩下的有效载荷
    {
        std::string res = Util::ReadOneLine(str, SEP);
        req._body.push_back(res);
    }

    req._path += req._url;                          // wwwroot/
    if (req._path[req._path.size() - 1] == '/') // 让它来到默认页面
        req._path += default_HomePage;

    auto pos = req._path.rfind(".");
    if (pos == std::string::npos)
        req._suffix += ".html";
    else
        req._suffix += req._path.substr(pos);
    return req;
}

std::string GetContentType(const std::string &suffix)
{
    std::string content_type = "Content-Type: ";
    if (suffix == ".html" || suffix == ".htm")
        content_type + "text/html";
    else if (suffix == ".css")
        content_type += "text/css";
    else if (suffix == ".js")
        content_type += "application/x-javascript";
    else if (suffix == ".png")
        content_type += "image/png";
    else if (suffix == ".jpg")
        content_type += "image/jpeg";
    else
    {
    }
    return content_type + SEP;
}

std::string HandlerHttp(std::string &message)
{
    // 1.读取请求
    // 这里省略

    // 2.反序列化和分析请求
    HttpRequest req = stringstream(message);

    // 3.使用请求
    std::string response;
    std::string body;
    if (Util::ReadFile(req._path, &body) == true)
    {
        response += "HTTP/1.0 200 OK" + SEP;
        response += "Content-Length: " + body.size();
        response += GetContentType(req._suffix);
        response += SEP;
        response += body;
    }
    else
    {
        response += "HTTP/1.0 404 Not Find" + SEP;
        Util::ReadFile("err_404.html", &body);
        response += "Content-Length: " + body.size();
        response += GetContentType(req._suffix);
        response += SEP;
        response += body;
    }

    return response;
}

void Usage(const std::string &proc)
{
    std::cout << proc << " serverPort" << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(USER_ERR);
    }
    uint16_t serverPort = atoi(argv[1]);
    ns_server* server = new ns_server(serverPort,HandlerHttp);
    server->InitServer();
    server->start();
    return 0;
}
